/*
 * @Author: xiaosihan
 * @Date: 2021-04-18 10:08:38
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2021-11-07 14:34:37
 */

import _ from "lodash";
import { ShapeBufferGeometry } from "three";
import Mesh, { MeshProps } from "../Mesh/Mesh";
import fontContorller from "./fontController";
export interface Text2DProps extends MeshProps {

    // 字体
    fontFamily?: "simhei" | "simkei"
    text?: string;
    size?: number;
    curveSegments?: number;
    textAlign?: "left_bottom" | "left_center" | "left_top" | "center_bottom" | "center_center" | "center_top" | "right_bottom" | "right_center" | "right_top"

    update?: (renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera, object3d: THREE.Object3D) => void; // 当文字加载过程中更新回调
}

export default class Text2D extends Mesh<Text2DProps> {
    constructor(props: Text2DProps) {
        super(props);
    }

    setGeometry() {
        const {
            fontFamily = "simhei",
            text = "<Text2D/>",
            size = 5,
            curveSegments = 1,
            textAlign = "left_Bottom",
            update
        } = this.props;

        const { renderer, scene, camera } = this.context;
        const { geometry, material } = this.object3d;

        // 参数都没有变时 无需重复创建 文字模型
        if (_.isEqual({ fontFamily, text, size, curveSegments, textAlign }, this.object3d.geometry.userData)) {
            return;
        }

        fontContorller.loadText({
            fontType: fontFamily,
            text: text,
            callback: THREEFont => {

                let Text2DGeometry = new ShapeBufferGeometry(THREEFont.generateShapes(text, size), curveSegments);

                Text2DGeometry.userData = {
                    fontFamily,
                    text,
                    size,
                    curveSegments,
                    textAlign
                }

                // 计算文字的位置
                Text2DGeometry.computeBoundingBox();

                if (Text2DGeometry.boundingBox) {

                    let { max, min } = Text2DGeometry.boundingBox;

                    let width = max.x - min.x;
                    let hieght = max.y - min.y;

                    if (["center_bottom", "center_center", "center_top"].includes(textAlign)) {
                        Text2DGeometry.translate((width / -2) - min.x, 0, 0);
                    }

                    if (["right_bottom", "right_center", "right_top"].includes(textAlign)) {
                        Text2DGeometry.translate((width / -1) - min.x, 0, 0);
                    }

                    if (["left_center", "center_center", "right_center"].includes(textAlign)) {
                        Text2DGeometry.translate(0, (hieght / -2) - min.y, 0);
                    }

                    if (["left_top", "center_top", "right_top"].includes(textAlign)) {
                        Text2DGeometry.translate(0, (-hieght) - min.y, 0);
                    }

                }
                this.object3d.geometry.dispose();
                this.object3d.geometry = Text2DGeometry;

                update && update(renderer, scene, camera, this.object3d);

            }
        });

    }

    componentWillUnmount() {
        this.object3d.geometry.dispose();
    }

    render() {
        return null;
    }

}